package main

import (
	"database/sql"
	"fmt"
	"github.com/fvbock/endless"
	_ "github.com/mattn/go-sqlite3"
	"html/template"
	"log"
	"net/http"
	"os"
	"syscall"
)

var Db *sql.DB

func main() {
	InitDB()
	var mux = http.NewServeMux()
	mux.HandleFunc("/", index)
	mux.HandleFunc("/add", add)
	server := endless.NewServer(":9999", mux)
	server.BeforeBegin = func(add string) {
		refreshPIDfile()
	}
	log.Fatal(server.ListenAndServe())
}

func Plus(x int, y int) int {
	return x + y
}

func index(w http.ResponseWriter, r *http.Request) {
	tl := template.New("layout")
	tl = tl.Funcs(template.FuncMap{"plus": Plus})
	tl, err := tl.ParseFiles("static/layout.html", "static/index.html")
	if err != nil {
		panic(err)
	}
	err = tl.ExecuteTemplate(w, "layout", GetAllDiary())
	if err != nil {
		showErr(w, err.Error())
	}
}

func add(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		tl, err := template.ParseFiles("static/layout.html", "static/add.html", "static/goback.html")
		if err != nil {
			panic(err)
		}
		_ = tl.ExecuteTemplate(w, "layout", "")
	} else {
		r.ParseForm()
		d := &Diary{
			Cls:     r.Form["cls"][0],
			Title:   r.Form["title"][0],
			Content: r.Form["content"][0],
		}
		_, err := PutDiary(d)
		if err != nil {
			showErr(w, err.Error())
		}
		http.Redirect(w, r, "/", http.StatusFound)
	}
}

func showErr(w http.ResponseWriter, errs string) {
	tl, err := template.ParseFiles("static/layout.html", "static/err.html", "static/goback.html")
	if err != nil {
		panic(err)
	}
	_ = tl.ExecuteTemplate(w, "layout", errs)
}

func refreshPIDfile() {
	pid := "./diary.pid"
	var pidfile *os.File
	var err error
	if !PathExists(pid) {
		pidfile, err = os.Create(pid)
	} else {
		pidfile, err = os.OpenFile(pid, os.O_WRONLY, os.ModeAppend)
	}
	if err != nil {
		panic(err)
	}
	defer pidfile.Close()
	_, err = fmt.Fprintf(pidfile, "%d", syscall.Getpid())
	if err != nil {
		panic(err)
	}
}

func PathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	return false
}
